package com.miyake.loveviewweb.client.service;

import java.util.List;
import java.util.Map;

import com.google.appengine.api.datastore.Key;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import com.miyake.loveviewweb.client.account.LoginInfo;
import com.miyake.loveviewweb.shared.model.ChartModel;
import com.miyake.loveviewweb.shared.model.ChartModel.ChartEngine;
import com.miyake.loveviewweb.shared.model.DataModel;
import com.miyake.loveviewweb.shared.model.FolderModel;
import com.miyake.loveviewweb.shared.model.GroupModel;
import com.miyake.loveviewweb.shared.model.ImageDataBodyModel;
import com.miyake.loveviewweb.shared.model.PluginModel;
import com.miyake.loveviewweb.shared.model.UserModel;
import com.miyake.loveviewweb.shared.model.ValueModel;

@RemoteServiceRelativePath("service.s3gwt")
public interface DataService extends RemoteService {
    /**
     * Utility class for simplifying access to the instance of async service.
     */
    public static class Util {
        private static DataServiceAsync instance;
        public static DataServiceAsync getInstance(){
            if (instance == null) {
                instance = GWT.create(DataService.class);
            }
            return instance;
        }
    }
    
    /* Common */
    void setSelectedItem(Key key);
    void delete(Key key);
    void delete(List<Key> keys);
    String keyToString(Key key);
    Key stringToKey(String key);
    
    /* Folder */
    // Set
    FolderModel createRootFolder(String name);
    FolderModel createFolder(String name, Key parentKey);
    void updateFolder(FolderModel folder);
    // Get
    List<FolderModel> getSubFolders(Key key);
    FolderModel getFolder(Key key);
    List<FolderModel> getRootFolders();
    void clearRootFolders();
    
    /* Data*/
    // Set
    DataModel createData(Key folder, String name, String text);
    void setChartListVisible(Key dataKey, boolean visible);
    void setChartColumns(Key dataKey, int columns);
   
    // Get
    DataModel getData(Key key, boolean content);
    List<Key> getDataKeyList(Key folderKey);
    List<DataModel> getDataList(Key folderKey ,boolean content);
    List<DataModel> getDataList(List<Key> dataKeys ,boolean content);
    List<DataModel> getSubDataList(Key dataKey, boolean content);
    
    // Update
    void updateData(DataModel data);
    void updateImageDataBodyModel(ImageDataBodyModel imageDataBodyModel);
    
    /* Chart */
    // Set
    ChartModel createChart(String name, Key dataKey, Map<String, String> axisDefine, ChartEngine chartEngine, Key pluginKey);
    void updateChart(ChartModel chartModel);
    void updateChartsSize(List<Key> keys, Integer width, Integer height);
    void updateChartSize(Key key, Integer width, Integer height);
    void updateChartEngine(List<Key> keys, ChartEngine chartEngine, Key pluginKey);
    // Get
    ChartModel getChart(Key key, boolean content);
    ChartModel getChart(Key key, boolean content, ChartModel.ChartEngine engine);
    List<ChartModel> getChartList(Key dataKey, boolean content);
    List<ChartModel> getChartList(List<Key> keys, boolean content);
    
    
    /* Plugin */
    // Set
    Key registerPlugin(String url) throws InvalidPluginException;
    void removePlugin(Key key);
    void removePlugins(List<Key> keys);
    void clearPlugins();
    Key executeDataProcessing(Key pluginKey, List<ValueModel> values, Map<String, String> data, Key sourceData);
    void parseFile(Key dataKey, Key pluginKey);
    // Get
    List<PluginModel> getPluginList(String type, String tag);
    List<PluginModel> getMyPluginList(String category, String tag);
    PluginModel getPlugin(Key key);
    List<ValueModel> getPluginSetting(Key pluginKey);

    // 
    void publish(Key contentKey, Key groupKey);
    
    
    // Login
    LoginInfo login(String requestUri);
    
    // User Management
    Key createUser() throws Exception;
    Key createUser(UserModel user) throws Exception;
    UserModel getMyProperty(); 
    List<UserModel> getAllUsers();
    List<UserModel> getUsers(List<Key> keys);
    UserModel getUser(Key key);
    void updateUser(UserModel userModel);
    void deleteUser(Key userKey);
    void deleteAllUsers();
    
    // Friend
    void addFriend(Key key);
    void byeFriend(Key key);
    List<UserModel> getMyFriends();
    
    // Group
    Key createGroup(String name);
    void deleteGroup(List<Key> keys);
    void deleteAllGroups();
    List<GroupModel> getAllGroups();
    List<GroupModel> getMyGroups();
    void joinGroup(Key groupKey);
    void leaveGroup(Key groupKey);
    
    // Plugin
    void installPlugins(List<Key> keys);
    void uninstallPlugins(List<Key> keys);
    List<PluginModel> getInstalledPlugins(String serviceType);
}
